package com.web.kdl.service.report;

import cn.hutool.core.util.ObjectUtil;
import com.web.kdl.common.result.CommonResult;
import com.web.kdl.controller.report.Report1Controller;
import com.web.kdl.dao.report.Report1Dao;
import com.web.kdl.daoV2.matrix.MatrixDao;
import com.web.kdl.daoV2.siteWheel.SiteWheelDao;
import com.web.kdl.entity.flywheelDataAnalysis.FlywheelDataAnalysis;
import com.web.kdl.entity.matrix.Matrix;
import com.web.kdl.pojo.Bo.MapSiteBo;
import com.web.kdl.pojo.Vo.EnergyDataVo;
import com.web.kdl.pojo.Vo.flywheel.FLywheelStatusVo;
import com.web.kdl.pojo.Vo.site.*;
import com.web.kdl.pojo.dto.SiteDto;
import com.web.kdl.service.createTable.TableDataType;
import com.web.kdl.service.flywheel.FlyWheelService;
import com.web.kdl.service.site.SiteService;
import com.web.kdl.service.site.SiteServiceImpl;
import com.web.kdl.util.RedisKeyUtil;
import com.web.kdl.util.RedisUtils;
import com.web.kdl.util.TableNameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zq
 * @date 2022/6/28 15:52
 */
@Service
public class Report1ServiceImpl implements Report1Service{

    @Autowired
    Report1Dao report1Dao;

    @Autowired
    FlyWheelService flyWheelService;

    @Autowired
    private SiteService siteService;
    @Resource
    MatrixDao matrixDao;
    @Resource
     RedisUtils redisUtils;
    private  List<Matrix> getWheelCount(String siteName){
        return siteService.getMatrixBySiteName(siteName);
    }

    @Resource
    SiteWheelDao siteWheelDao;

    private static final Logger logger = LoggerFactory.getLogger(Report1Controller.class);
    @Override
    public CommonResult getAllDetailSite(SiteDto dto) {
            // 站点详细信息获取
            // 电机转速.转子温度 充电计数 放电计数 系统放电功率 系统充电功率
            // 结果集
            ArrayList<SiteDetailVo> siteDetailVos = new ArrayList<>();
            try {
                String siteName=dto.getSiteName();
                List<Matrix> matrixList = getWheelCount(siteName);
                if (matrixList.size() ==0)
                    return CommonResult.error("未添加该站点阵列数据");
                for (Matrix matrix : matrixList)
                {
                    for ( int i = 1; i <= matrix.getWheelNumber(); i++)
                    {
                        String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                        // 对应 matrix id 下的 flywheel i 飞轮数据
                        List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                        if (ObjectUtil.isEmpty(list))
                            continue;
                        siteDetailVos.add(new SiteDetailVo(list));

                    }
                }
                // 获取 需要查询的所有飞轮表名
//                List<String> tableList = TableNameUtils.getAllDataTableName(matrixList, siteName, TableDataType.DAY);
//                for (String table : tableList) {
//                    List<FlywheelMainDto> allDetailSite = report1Dao.getAllDatailSite(table); //查询data表所有数据
//                    logger.info(allDetailSite.toString());
//                    if (ObjectUtil.isEmpty(allDetailSite)){
//                        continue;
//                    }
//                    siteDetailVos.add(new SiteDetailVo(allDetailSite));
//                }
                return CommonResult.success(siteDetailVos);
            } catch (Exception e) {
                logger.error("获取站点详细信息时出错: " ,e);
                return CommonResult.error("该站点数据未添加");
            }
    }

    @Override
    public CommonResult getSiteBaseInfo(SiteDto dto) {
        try {
            String siteName = dto.getSiteName();
            List<Matrix> matrixList = getWheelCount(siteName);
            if (matrixList.size() ==0)
                return CommonResult.error("未添加该站点阵列数据");
            SiteBaseVo siteBaseVo = new SiteBaseVo();
            //1.站点信息
            //1.1 系统状态 （待定) TODO
            //1.2 系统容量  (所有飞轮总和)
            //1.3 累计充电量和放电量 (所有飞轮总和)
            // 2. 工作状态 待定
            for (Matrix matrix : matrixList)
            {
                for ( int i = 1; i <= matrix.getWheelNumber(); i++)
                {
                    String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                    // 对应 matrix id 下的 flywheel i 飞轮数据
                    List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                    if (ObjectUtil.isEmpty(list))
                        continue;
                    siteBaseVo.add(Optional.ofNullable(list).orElse(Collections.emptyList()));

                }
            }
//            List<String> Tablelist = TableNameUtils.getAllDataTableName(matrixList, siteName, TableDataType.DAY);
//            for (String table : Tablelist){
//                List<FlywheelMainDto> dataDto = report1Dao.getWheelForSite(table);
//                siteBaseVo.add(Optional.ofNullable(dataDto).orElse(Collections.emptyList()));
//            }
            siteBaseVo.setSiteStatus("正常运行");
            siteBaseVo.formatValues();
            return CommonResult.success(siteBaseVo);
        } catch (Exception e) {
            return CommonResult.error("该站点数据未添加");
        }
    }

    @Override
    public CommonResult getRecent7DaysDailyMaxPower(SiteDto dto) {
        try {
            String siteName=dto.getSiteName();
            List<Matrix> matrixList = getWheelCount(siteName);
            if (matrixList.size() ==0)
                return CommonResult.error("未添加该站点阵列数据");
            List<String> tablelist = TableNameUtils.getAllDataTableName(matrixList, siteName, TableDataType.TEMP);
            // 查询当前时间 往前推1天的站点下 各飞轮的近一天实时功率
            List<SumSiteCurrentPowerVo> powerList = report1Dao.getCurrentPower(tablelist);
            List<SitePowerVo> sitePowerVos = powerList.stream()
                    .collect(Collectors.groupingBy(
                            vo -> {
                                // 将 String 转 LocalDateTime
                                return vo.getTime().truncatedTo(ChronoUnit.MINUTES);
                            },
                            Collectors.collectingAndThen(
                                    Collectors.toList(),
                                    list -> {
                                        double inPower = list.stream()
                                                .filter(item -> "系统可充电功率".equals(item.getDeviceName()))
                                                .mapToDouble(SumSiteCurrentPowerVo::getPowerValue)
                                                .sum();

                                        double outPower = list.stream()
                                                .filter(item -> "系统可放电功率".equals(item.getDeviceName()))
                                                .mapToDouble(SumSiteCurrentPowerVo::getPowerValue)
                                                .sum();

                                        return new SitePowerVo(siteName, list.get(0).getTime(), inPower, outPower);
                                    }
                            )
                    ))
                    .values().stream()
//                .reversed() 为倒序
                    .sorted(Comparator.comparing(SitePowerVo::getTime))
                    .collect(Collectors.toList());


            return CommonResult.success(sitePowerVos);
        } catch (Exception e) {
            return CommonResult.error("该站点数据未添加");
        }

    }

    @Override
    public CommonResult<List<EnergyDataVo>> getAllFlywheelEleCount(SiteDto dto) {

            String siteName=dto.getSiteName();
            List<Matrix> matrixList = getWheelCount(siteName);
            if (matrixList.size() ==0)
                return CommonResult.error("未添加该站点阵列数据");
            // TODO 待修改 2025-10-27 20:00
//        ArrayList<EnergyDataVo> energyDataVos = new ArrayList<>();
        // 获取 day表中的数据
        List<String> tablelist = TableNameUtils.getAllDataTableName(matrixList, siteName, TableDataType.DAY);
        List<EnergyDataVo> allFlywheelEleCount = flyWheelService.getAllFlywheelEleCount(tablelist);

        // 当前天 是否是新月的第一天
        // 若不是 将最新数据替换 sysEleVos 中的 对应月份
        // 若是新月 第一天 则将数据加入
        EnergyDataVo energyDataVo = new EnergyDataVo();
        // 统计当前 上次飞轮列表的 总充电量和 总放电量
        List<Matrix> matrixs = matrixDao.selectList(null);
        for (Matrix matrix : matrixs)
        {
            for ( int i = 1; i <= matrix.getWheelNumber(); i++)
            {
                String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                //  存储的是每个飞轮 当前时间节点的最新数据
                List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                if (list == null || list.isEmpty()) {
                    continue;
                }
                energyDataVo.setTime(list.get(0).getMonth());
                for (FlywheelDataAnalysis flywheelData : list) {
                    if ( flywheelData.getDeviceName().equals("总充电量")){
                        energyDataVo.Add(flywheelData.getDataValue(),0);
                    }else if (flywheelData.getDeviceName().equals("总放电量")){
                        energyDataVo.Add(0,flywheelData.getDataValue());
                    }
                }
            }
        }
        if (energyDataVo.getTime() != null && ObjectUtil.isNotEmpty(allFlywheelEleCount))
        SiteServiceImpl.existingRecord(allFlywheelEleCount, energyDataVo);
        return CommonResult.success(allFlywheelEleCount);

    }

    // alert 表
    @Override
    public CommonResult getSiteMonMsg(SiteDto dto) {
        try {
            String siteName=dto.getSiteName();
            List<Matrix> matrixList = getWheelCount(siteName);
            if (matrixList.size() ==0)
                return CommonResult.error("未添加该站点阵列数据");
            List<String> tablelist = TableNameUtils.getAllAlertTableName(matrixList, siteName);
            List<SiteMonVo> siteMonList = new ArrayList<>();
            for (String table : tablelist){
                List<SiteMonVo> res= report1Dao.getSiteMonMsg(table);
                siteMonList.addAll(Optional.ofNullable(res).orElse(Collections.emptyList()));
            }
            return CommonResult.success(siteMonList);
        } catch (Exception e) {
            return CommonResult.error("该站点数据未添加");
        }

    }

    @Override
    public CommonResult getAllFlywheelStatus(SiteDto dto) {
        String siteName=dto.getSiteName();
        List<Matrix> matrixList = getWheelCount(siteName);
        // 统计所有 matrix 的 飞轮数量总和
        int totalWheelCount = matrixList.stream()
                .mapToInt(Matrix::getWheelNumber)
                .sum();
        if (matrixList.size() ==0)
            return CommonResult.error("未添加该站点阵列数据");
        List<String> tablelist = TableNameUtils.getAllStatusTableName(matrixList, siteName);
        FLywheelStatusVo statusVo = new FLywheelStatusVo();
        statusVo.setFlywheelCount(totalWheelCount);
        for (String table : tablelist){
            String flyWheelStatus = report1Dao.getFlyWheelStatus(table);
            if (flyWheelStatus != null){
                if(flyWheelStatus.equals("系统关机")){
                    statusVo.addStandbyCount();
                }else{
                    statusVo.addRunCount();
                }
            }else{
                statusVo.addErrorCount();
            }
        }
        return CommonResult.success(statusVo);
    }

    @Override
    public CommonResult getSiteInfoForMap(SiteDto dto) {
        try {
            String siteName = dto.getSiteName();
            List<Matrix> matrixList = getWheelCount(siteName);
            if (matrixList.size() ==0)
                return CommonResult.error("未添加该站点阵列数据");
            MapSiteBo Bo = new MapSiteBo();
            for (Matrix matrix : matrixList)
            {
                for ( int i = 1; i <= matrix.getWheelNumber(); i++)
                {
                    String redisKey = RedisKeyUtil.getRedisKey(matrix.getId(), i);
                    // 对应 matrix id 下的 flywheel i 飞轮数据
                    List<FlywheelDataAnalysis> list = redisUtils.getMap(redisKey, FlywheelDataAnalysis.class);
                    if (ObjectUtil.isEmpty(list))
                        continue;
                    Bo.add(Optional.ofNullable(list).orElse(Collections.emptyList()));
                }
            }
            // 构建VO 计算 返回结果
            MapSiteVo mapSiteVo = new MapSiteVo(Bo);
            return CommonResult.success(mapSiteVo);
        } catch (Exception e) {
            return CommonResult.error("该站点数据未添加");
        }
    }
}
